home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ncsa / Mac / Telnet2.6 / prerelease / d4 / Telnet2.6.1d4.src.sit.hqx / Telnet 2.6.1d4 source / source / ftp / binsubs.c next >
Encoding:
C/C++ Source or Header  |  1994-11-22  |  10.9 KB  |  454 lines

  1. /****************************************************************
  2. *    NCSA Telnet for the Macintosh                                *
  3. *                                                                *
  4. *    National Center for Supercomputing Applications                *
  5. *    Software Development Group                                    *
  6. *    152 Computing Applications Building                            *
  7. *    605 E. Springfield Ave.                                        *
  8. *    Champaign, IL  61820                                        *
  9. *                                                                *
  10. *    Copyright (c) 1986-1993,                                    *
  11. *    Board of Trustees of the University of Illinois                *
  12. *****************************************************************
  13. *    MacBinary Subroutines.    
  14. */
  15.  
  16. #ifdef MPW
  17. #pragma segment FTPServer
  18. #endif
  19.  
  20. #include <stdio.h>
  21. #include <string.h>
  22.  
  23. #include "TelnetHeader.h"
  24. #include "maclook.proto.h"
  25. #include "bkgr.proto.h"
  26. #include "MacBinary.h"
  27. #include "telneterrors.h"
  28. #include "binsubs.proto.h"
  29. #include "translate.proto.h"
  30. #include "debug.h"
  31. #include "DlogUtils.proto.h"    // For WriteZero
  32.  
  33. static    unsigned short    CalculateCRC(unsigned char *ptr, short count, unsigned short crc);
  34. static    void SetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop);
  35. static    void MakeTextFile(short volume, long dirID, StringPtr name, HFileParam *iop);
  36. static    short isMacBinary(MBHead *p);
  37. static    OSErr bwrite( MBFile *out, char *buffer, long size);
  38. static    void ProcessMBHead (MBFile *out, MBHead *header);
  39.  
  40. extern    MBFile        /* BYU */
  41.     *mbfp;            /* BYU */
  42.  
  43. #define BLOCKS(x)    ((x+127)/128)
  44. /*#define lmove(f,t)    memmove(f,t,(size_t) 4)        /* BYU LSC */
  45.  
  46. MBHead    *mbh;
  47. char    buffer[128];
  48.  
  49. unsigned short    CalculateCRC(unsigned char *ptr, short count, unsigned short crc)
  50. {
  51.     unsigned short    i;
  52.     
  53.     crc = 0;
  54.     while (count -- > 0) {
  55.         crc = crc ^ (unsigned short)*ptr++ << 8;
  56.         for (i = 0; i < 8; i++)
  57.             if (crc & 0x8000)
  58.                 crc = crc << 1 ^ 0x1021;
  59.             else
  60.                 crc = crc << 1;
  61.     }
  62.     
  63.     return crc;
  64. }
  65.  
  66. void GetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop)
  67. {
  68.     iop->ioNamePtr = name;
  69.     iop->ioVRefNum = volume;
  70.     iop->ioDirID = dirID;
  71.     iop->ioFVersNum = 0;
  72.     iop->ioFDirIndex = 0;
  73.     PBHGetFInfo((HParmBlkPtr) iop, FALSE);
  74. }
  75.  
  76. void SetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop)
  77. {
  78.     iop->ioNamePtr = name;
  79.     iop->ioVRefNum = volume;
  80.     iop->ioDirID = dirID;
  81.     iop->ioFVersNum = 0;
  82.     iop->ioFDirIndex = 0;
  83.     PBHSetFInfo((HParmBlkPtr) iop, FALSE);
  84. }
  85.  
  86. void MakeTextFile(short volume, long dirID, StringPtr name, HFileParam *iop)
  87. {
  88.     GetFileInfo(volume, dirID, name, iop);
  89.     iop->ioFlFndrInfo.fdType = 'TEXT';
  90.     iop->ioFlFndrInfo.fdCreator = gFTPServerPrefs->TextCreator;
  91.     SetFileInfo(volume, dirID, name, iop);
  92. }
  93.  
  94. short isMacBinary(MBHead *p)
  95. {
  96.     unsigned short    crc;
  97.     
  98.     if ((p->nlen > 0)   &&    (p->nlen < 65)  &&
  99.         (p->zero1 == 0) &&    (p->zero2 == 0) && (p->zero3 == 0))    {    // Assume MB I
  100.             crc = CalculateCRC((unsigned char *)p, 124, 0);
  101.             if (((short)p->crc == crc) && (p->mb2versnum > 128))    {        // Check for MB II
  102.                 if (p->mb2minvers > 129)
  103.                     return(0);            // If vers is greater than 129, leave it alone
  104.                 
  105.                 return (1);                // Valid MB II file.
  106.             }
  107.             else {            
  108.                 p->flags2 = 0;            // So we can use same routines for MB I & II
  109.                 return (1);                // Valid MB I file (we make it a II file on the fly.)
  110.                 }
  111.         }
  112.  
  113.     return(0);                            // Not a Macbinary file            
  114. }
  115.  
  116. long MBsize( MBFile *mbfp)
  117. {
  118.     long size = 0;
  119.     OSErr ret;
  120.     
  121.     ret = GetEOF( mbfp->fd, &size );            /* length of file data fork */
  122.     if (ret != noErr) 
  123.         size = 0;
  124.  
  125.     return(size);
  126. }
  127.  
  128. MBFile *MBopen(char *file, short vrefnum, long dirID, short mode)
  129. {
  130.     MBFile *mbfp;
  131.     OSErr err;
  132.  
  133.     if ((mbfp = (MBFile *) NewPtrClear(sizeof(MBFile))) == NULL)
  134.         return(NULL);
  135.  
  136.     if (gFTPServerPrefs->DoISOtranslation)                // MP: translation method
  137.         trbuf_ftp_mac((unsigned char *)file, strlen(file));
  138.  
  139.     BlockMove(file, mbfp->name, 32);
  140.     if (strlen(file) > 31)
  141.         mbfp->name[31] = 0;
  142.  
  143.     if (gFTPServerPrefs->DoISOtranslation)
  144.         trbuf_mac_ftp((unsigned char *)file, strlen(file));                // MP: translation method
  145.  
  146.     c2pstr((char *)mbfp->name);
  147.     mbfp->vrefnum = vrefnum;
  148.     mbfp->dirID = dirID;
  149.     mbfp->mode = mode;
  150.  
  151.     if ((err = HOpen( vrefnum, dirID, mbfp->name, fsRdWrPerm, &mbfp->fd)) != noErr) {
  152.         if ((err==-43) && (mode & MB_WRITE)) {
  153.             HCreate( vrefnum, dirID, mbfp->name, gFTPServerPrefs->BinaryCreator,
  154.                         gFTPServerPrefs->BinaryType);
  155.             if (mode & MB_ISASCII)    {
  156.                 HFileParam blah;
  157.                 MakeTextFile(vrefnum, dirID, mbfp->name, &blah);
  158.                 }
  159.                 
  160.             if (HOpen( vrefnum, dirID, mbfp->name, fsRdWrPerm, &mbfp->fd)) 
  161.                 return( 0L);
  162.             }
  163.         else 
  164.             return(0L);
  165.         }
  166.  
  167.     if (mode & MB_APPEND)
  168.         SetFPos(mbfp->fd,fsFromLEOF,0);
  169.  
  170.     mbfp->binary=0;
  171.     mbfp->sector1=1;
  172.     mbfp->fork=0;
  173.     return( mbfp);
  174. }
  175.  
  176. OSErr bwrite( MBFile *out, char *buffer, long size)
  177. {
  178.     long len = size;
  179.     OSErr error = noErr;
  180.  
  181.     if (out->binary) {
  182.         if (out->bytes > 0) {
  183.             if (out->bytes < len) len = out->bytes;
  184.             error= FSWrite( out->fd, &len, buffer);
  185.             out->bytes -= len;
  186.             buffer +=len;
  187.             size -= len;
  188.             }
  189.         if (out->bytes <= 0) {
  190.             if (!out->fork) {
  191.                 out->fork = 1;
  192.                 out->bytes = BLOCKS(out->rlen)*128;
  193.                 SetEOF( out->fd, (long) out->dlen);
  194.                 FSClose( out->fd);
  195.                 if (out->bytes) {
  196.                     HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd);
  197.                     if (size) {
  198.                         len = (long) size;
  199.                         error= FSWrite( out->fd, &len, buffer);
  200.                         }
  201.                     }
  202.                 else
  203.                     out->fd = 0;
  204.                 }
  205.             else SetEOF( out->fd, (long) out->rlen);
  206.             }
  207.         }
  208.     else {
  209.         error = FSWrite( out->fd, &len, buffer);
  210.         }
  211.     return (error);
  212. }
  213.  
  214. void ProcessMBHead (MBFile *out, MBHead *header)
  215. {
  216.     OSErr    err;
  217.  
  218.     BlockMove(header, &out->header, sizeof(MBHead));
  219.     out->binary = 1;
  220.     BlockMove(&header->dflen[0], &out->dlen, 4);
  221.     BlockMove(&header->rflen[0], &out->rlen, 4);
  222.     out->bytes = BLOCKS(out->dlen)*128;
  223.     out->fork = 0;
  224.     out->sector1 = 0;
  225.  
  226.     FSClose(out->fd);
  227.     if (HDelete( out->vrefnum, out->dirID, out->name))            /* Error deleting Old File */
  228.         DoError (200 | RESOURCE_ERRORCLASS, LEVEL1, NULL);
  229.         
  230.     BlockMove(&out->header.nlen, out->name, 32);
  231.  
  232. #if 0                                                            /* BYU 2.4.17 */
  233.     MBstat( &out->header.nlen, 1, (long)(BLOCKS(out->dlen)+BLOCKS(out->rlen)) );
  234. #endif                                                            /* BYU 2.4.17 */
  235.  
  236.     if (out->bytes) {
  237.         if ((err=HOpen( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) != noErr) {
  238.             if (err == -43) {
  239.                 long    cre,typ;
  240.                 
  241.                 BlockMove(out->header.type, &typ,  4);
  242.                 BlockMove(out->header.creator, &cre, 4);
  243.  
  244.                 HCreate( out->vrefnum, out->dirID, out->name, cre, typ);
  245.                 if (HOpen(out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) 
  246.                     return;
  247.                 }
  248.             else {
  249.                 return;
  250.                 }
  251.             }
  252.         }
  253.     else {
  254.         if ((err=HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) != noErr) {
  255.             if (err == -43) {
  256.                 long    cre,typ;
  257.  
  258.                 BlockMove(out->header.type, &typ, 4);
  259.                 BlockMove(out->header.creator, &cre, 4);
  260.  
  261.                 HCreate( out->vrefnum, out->dirID, out->name, cre, typ);
  262.                 if (HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) 
  263.                     return;
  264.                 }
  265.             else {
  266.                 return;
  267.                 }
  268.             }
  269.         out->fork = 1;
  270.         out->bytes=BLOCKS(out->rlen)*128;
  271.         }
  272. }
  273.  
  274. long MBwrite(
  275.     MBFile *out,
  276.     void *buffer,    /* BYU LSC */
  277.     long size
  278.   )
  279. {
  280.     long    rsize;
  281.     
  282.     if (size < 1)
  283.         return(0);
  284.  
  285.     rsize=size;
  286.  
  287.     if (out->sector1 && (size >= sizeof(struct MBHead)) && (!(out->mode & MB_DISABLE)))  {
  288.         if (isMacBinary((MBHead *) buffer)) {            // WARNING: isMacBinary modifies data
  289.             ProcessMBHead( out, (MBHead *) buffer);
  290.             buffer = (void *)((char *)buffer + 128);
  291.             if ((size-=128) <1)
  292.                 return(rsize);
  293.             }
  294.         }
  295.  
  296.     if (bwrite( out,buffer,size))
  297.         return(-1);
  298.     else
  299.         return( rsize);
  300. }
  301.  
  302. void MBclose( MBFile *out)
  303. {
  304.     HFileParam finfo;
  305.     long fpos;
  306.     
  307.     if (!out->fd) {
  308.         if (out != NULL) DisposPtr((Ptr)out);
  309.         return;
  310.         }
  311.  
  312.     if (!(out->mode & MB_DISABLE) && (out->mode & MB_WRITE)) {
  313.         if (out->fork)
  314.             SetEOF( out->fd, (long) out->rlen);
  315.         else
  316.             SetEOF( out->fd, (long) out->dlen);
  317.  
  318.         FSClose( out->fd);
  319.  
  320.         GetFileInfo( out->vrefnum, out->dirID, out->name, &finfo);
  321.         BlockMove(&out->header.type[0], &finfo.ioFlFndrInfo, sizeof(FInfo));
  322.         BlockMove(&out->header.cdate[0], &finfo.ioFlCrDat, 4);
  323.         BlockMove(&out->header.mdate[0], &finfo.ioFlMdDat, 4);
  324.         finfo.ioFlFndrInfo.fdFlags &= 0xfeff;
  325.         finfo.ioFlFndrInfo.fdFlags |= (out->header.flags2 & 0x00FF);
  326.         finfo.ioFlRLgLen=out->rlen;
  327.         finfo.ioFlLgLen =out->dlen;
  328.     
  329.         SetFileInfo( out->vrefnum, out->dirID, out->name, &finfo);
  330.         }
  331.     else if (out->mode & MB_WRITE) {
  332.         GetFPos( out->fd, &fpos);
  333.         SetEOF(  out->fd,  fpos);
  334.         FSClose( out->fd);
  335.         }
  336.     else
  337.         FSClose( out->fd);
  338.     
  339.     DisposPtr((Ptr) out);                    /* JMB 2.6 -- Nice memory leak, no? */
  340. }
  341.  
  342. long MBread
  343.   (
  344.     MBFile *in,
  345.     void *buffer,
  346.     long size
  347.   )
  348. {
  349.     char            *p;
  350.     long            rsize=size;
  351.     unsigned short    crc;
  352.  
  353.     if (in->fork<0) {
  354.         return(-1);
  355.         }
  356.  
  357.     p = buffer;
  358.     
  359.     if (in->sector1) {
  360.         HFileParam finfo;
  361.  
  362. //        setmem( &in->header, sizeof(MBHead), 0);
  363.         WriteZero((Ptr)&in->header, sizeof(MBHead));
  364.         BlockMove(in->name, &in->header.nlen, (Length(in->name) > 31) ? 32 : (Length(in->name)+1));
  365.         GetFileInfo( in->vrefnum, in->dirID, in->name, &finfo);
  366.         BlockMove(&finfo.ioFlFndrInfo, &in->header.type[0], sizeof(FInfo) );
  367.         in->header.flags2 = finfo.ioFlFndrInfo.fdFlags & 0x00FF;
  368.         in->header.protected = (in->header.zero2 & 0x40)?1:0;
  369.         in->header.zero2 = 0;
  370.         BlockMove(&finfo.ioFlLgLen, &in->header.dflen[0], 4);
  371.         BlockMove(&finfo.ioFlRLgLen, &in->header.rflen[0], 4);
  372.         BlockMove(&finfo.ioFlCrDat, &in->header.cdate[0], 4);
  373.         BlockMove(&finfo.ioFlMdDat, &in->header.mdate[0], 4);
  374.         in->header.mb2versnum = 129;
  375.         in->header.mb2minvers = 129;
  376.         crc = CalculateCRC((unsigned char *) &(in->header), 124, 0);
  377.         BlockMove(&crc, &(in->header.crc), 2);
  378.         
  379.         in->dlen=finfo.ioFlLgLen;
  380.         in->rlen=finfo.ioFlRLgLen;
  381.         
  382.         if (! (in->mode & MB_DISABLE) ) {
  383.             if (size<128) return(-1);
  384.  
  385.             BlockMove(&in->header, p, 128);
  386.             p +=128;
  387.             size -= 128;
  388.             in->bytes= BLOCKS(in->dlen)*128;
  389.             in->binary=1;
  390.             }
  391.         else {
  392.             in->bytes = in->dlen;
  393.             in->rlen=0;
  394.             in->binary=0;
  395.             }
  396.         in->sector1=0;
  397. #if 0                                                            /* BYU 2.4.17 */
  398.         MBstat( &in->header.nlen, 1, (long) (BLOCKS(in->dlen)+BLOCKS(in->rlen)) );
  399. #endif                                                            /* BYU 2.4.17 */
  400.         }
  401.  
  402.     if ( size >0) {
  403.         long length = size;
  404.         OSErr err;
  405.  
  406.         err = FSRead( in->fd, &length, p);
  407.  
  408.         size -= length;
  409.         in->bytes -=length;
  410.         p += length;
  411.  
  412.         if (err == -39 || (in->bytes<=0) ) {
  413.             FSClose( in->fd );
  414.             if (in->bytes<0L) in->bytes=0L;
  415. //            setmem(p, in->bytes, 0);            //    Make filler bytes zero
  416.             WriteZero(p, in->bytes);
  417.             size -= in->bytes;
  418.             p    +=      in->bytes;                /* Make adjustments for necessary 128 byte term */
  419.             if (!in->fork ) {
  420.                 in->fork=1;
  421.                 in->bytes= BLOCKS(in->rlen)*128;
  422.                 if (in->bytes) {
  423.                     HOpenRF( in->vrefnum, in->dirID, in->name, fsRdWrPerm, &in->fd);
  424. #ifdef READ
  425.                     length=(long)size;
  426.                     if (length >0L) {
  427.                         err = FSRead( in->fd, &length, p);
  428.                         size -= length;
  429.                         in->bytes -=length;
  430.                         }
  431. #endif READ
  432.                     }
  433.                 else {
  434.                     in->fd=0;
  435.                     in->fork=-1;                    /* Time to close up shop */
  436.                     }
  437.                 }
  438.             else {
  439.                 in->fd=0;
  440.                 in->fork=-1;                    /* Time to close up shop */
  441.                 }
  442.             }
  443.         }
  444.     return( rsize-size); 
  445. }
  446.  
  447. void init_mb_files(void) {            /* BYU */
  448.   mbfp->fd = 0;                /* BYU */
  449. }                            /* BYU */
  450.                             /* BYU */
  451. void close_mb_files(void) {            /* BYU */
  452.     if (mbfp->fd != 0) MBclose( mbfp );                /* BYU - close input file */
  453. }                            /* BYU */
  454.